package main

import (
	"log"
	"math/rand"
	"sync"
	"time"
)

/*
一个消费者，多个生产者
*/
func main() {

	rand.Seed(time.Now().UnixNano())
	log.SetFlags(0)

	const Max = 100000
	const NumSenders = 1000
	wgReceivers := sync.WaitGroup{}
	wgReceivers.Add(1)

	dataCh := make(chan int)
	stopCh := make(chan struct{})

	for i := 0; i < NumSenders; i++ {
		go func() {

			select {

			case <-stopCh: // 当 stopCh关闭后，此处永远不会堵塞
				return
			default:

			}

			select {
			case <-stopCh: // 如果 stopCh 已经关闭，则表明不需要生产了
				return
			case dataCh <- rand.Intn(Max): // 生产者发送值
			}

		}()
	}
	// 当一个 channel 不被任何 goroutine 使用时， 它将被 GC 掉

	go func() {
		defer wgReceivers.Done()
		for value := range dataCh {
			if value == Max-1 { // 通知 生产者不要生产了
				close(stopCh)

				return
			}
			log.Println(value)
		}
	}()

	wgReceivers.Wait()

}
